#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "network.h"

int is_ip_valid(char * url)
{
  char c;
  int i, ip[4];
  int result = sscanf(url, "%d.%d.%d.%d%c", &ip[0], &ip[1], &ip[2], &ip[3], &c);

  if (result != 4)
    return 0;

  for (i = 0; i < 4; i++)
    if (ip[i] < 0 || ip[i] > 255)
      return 0;

  return 1;
}

void url_to_adress(char * url, struct sockaddr_in * adress)
{    
  adress->sin_family = AF_INET;
  adress->sin_port = htons(PORT);
  if (is_ip_valid(url)) {
    adress->sin_addr.s_addr = inet_addr(url);  
  } else {
    struct hostent *resolv = gethostbyname(url);
    error_if(resolv == 0, "Unable to resolve adress");
    adress->sin_addr.s_addr = *(long*)resolv->h_addr;
  }
}

int socket_open(char * url) 
{
  int socket_id = socket(AF_INET, SOCK_STREAM, 0);
  error_if(socket_id < 0, "Unanable to create socket");

  struct sockaddr_in adress;
  url_to_adress(url, &adress);

  int connect_result = connect(socket_id, (struct sockaddr*)&adress, sizeof(struct sockaddr_in));
  error_if(connect_result < 0, "Unanable to connect");

  return socket_id;
}

int server_socket_open(short int port) 
{
  int socket_id = socket(AF_INET, SOCK_STREAM, 0);
  error_if(socket_id < 0, "Unanable to create socket");

  struct sockaddr_in adress;
  adress.sin_family = AF_INET;
  adress.sin_port = htons(port);
  adress.sin_addr.s_addr = htonl(INADDR_ANY);

  int opt = 1;
  int opt_result = setsockopt (socket_id, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
  error_if(opt_result < 0, "Unanable to set socket options");

  int bind_result = bind(socket_id, (struct sockaddr*)&adress, sizeof(struct sockaddr_in));
  error_if(bind_result < 0, "Unanable to bind");  
  return socket_id;
}


int server_socket_accept(int server_socket_id, struct sockaddr_in * client_adress)
{
  socklen_t socket_length = sizeof(struct sockaddr_in);

  int listen_result = listen(server_socket_id,5);
  error_if(listen_result < 0, "Unanable to listen");  

  int client_socket_id = accept(server_socket_id, (struct sockaddr *) client_adress, &socket_length);
  error_if(client_socket_id < 0, "Unanable to accept");

  return client_socket_id;
}


